package org.kermeta.spem.activityautomation.eclipse.commitseveralprojectssvn;

import java.io.File;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.ui.PlatformUI;
import org.kermeta.spem.activityautomationmanager.ActivityAutomation;
import org.kermeta.spem.executioncontext.ExecutionContext;
import org.kermeta.spem.processexecution.utils.model.ModelUtils;
import org.kermeta.spem.versioncontrolsystem.SVNClient;
import org.tigris.subversion.subclipse.ui.operations.CleanupOperation;
import org.tigris.subversion.svnclientadapter.ISVNInfo;
import org.tigris.subversion.svnclientadapter.ISVNStatus;
import org.tigris.subversion.svnclientadapter.SVNStatusKind;

public class CommitSeveralProjectsSVNActivityAutomation implements
ActivityAutomation {

	public CommitSeveralProjectsSVNActivityAutomation() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void run(String contextModelPath) {
		//Get the execution context
		ExecutionContext executionContext = ModelUtils.getExecutionContextRoot(contextModelPath);

		//Get the URL of the SVN repository
		String svnRepositoryURL = ModelUtils.getValueOfKey("url of the remote repository", executionContext);

		//Get an SVN client
		SVNClient svnClient = new SVNClient();

		//Get the projects of the workspace
		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();

		//Count the number of projects to commit
		int numberOfProjectsToCommit = 0;
		for(IProject project : projects){
			ISVNInfo info = svnClient.getInfoFromWorkingCopy(project.getLocation().toFile());
			if(info != null){
				String url = info.getUrlString();
				String projectName = project.getName();
				String repoURL = url.substring(0, url.indexOf(projectName)-1);
				if(repoURL.equals(svnRepositoryURL)){
					numberOfProjectsToCommit++;
				}
			}
		}

		//Creation of the list of projects to commit
		File[] filesToCommit = new File[numberOfProjectsToCommit];
		IProject[] projectsToCommit = new IProject[numberOfProjectsToCommit];

		//Select the projects to commit
		int j = 0;
		for(int i = 0; i<projects.length; i++){
			ISVNInfo info = svnClient.getInfoFromWorkingCopy(projects[i].getLocation().toFile());
			if(info != null){
				String url = info.getUrlString();
				String projectName = projects[i].getName();
				String repoURL = url.substring(0, url.indexOf(projectName)-1);
				if(repoURL.equals(svnRepositoryURL)){
					filesToCommit[j] = projects[i].getLocation().toFile();
					projectsToCommit[j] = projects[i];
					j++;
				}
			}
		}

		//Add the project's resources to version control if they are unversioned, except for the bin directory
		for(IProject project : projectsToCommit){
			try {
				addResourcesToVersionControlExceptBinDirectory(project.members(), svnClient);
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		//Commit the projects
		svnClient.commit(filesToCommit, "Commit of the modified projects.", true);

		//Refresh the projects
		try {
			new CleanupOperation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart(), projectsToCommit).run();
		} catch (InvocationTargetException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		


	}

	public void addResourcesToVersionControlExceptBinDirectory(IResource[] resources, SVNClient svnClient){
		for (IResource res : resources) {
			if (res instanceof IFolder) {
				IFolder folder = (IFolder) res;
				if (!folder.getName().equals("bin")) {
					ISVNStatus status = svnClient.getSingleStatus(folder.getLocation().toFile());
					if(status.getTextStatus().equals(SVNStatusKind.UNVERSIONED)){
						svnClient.addDirectory(folder.getLocation().toFile(), true);
					}
					try {
						addResourcesToVersionControlExceptBinDirectory(folder.members(), svnClient);
					} catch (CoreException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if (folder.getName().equals("bin")) {
					ISVNStatus status = svnClient.getSingleStatus(folder.getLocation().toFile());
					if(!status.getTextStatus().equals(SVNStatusKind.IGNORED)){
						svnClient.addToIgnoredPatterns(folder.getLocation().toFile(), "bin");
					}
				}
			} else if (res instanceof IFile) {
				File file = ((IFile) res).getLocation().toFile();
				ISVNStatus status = svnClient.getSingleStatus(file);
				if(status.getTextStatus().equals(SVNStatusKind.UNVERSIONED)){
					svnClient.addFile(file);
				}
			}
		}

	}

}
